home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_014 / amiga3d / displayuniverse.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  11KB  |  444 lines

  1. #include <exec/types.h>
  2. #include <exec/nodes.h>
  3. #include <exec/lists.h>
  4. #include <exec/memory.h>
  5. #include <hardware/blit.h>
  6. #include <hardware/custom.h>
  7. #include <graphics/gfx.h>
  8. #include <graphics/clip.h>
  9. #include <graphics/rastport.h>
  10. #include <graphics/view.h>
  11. #include <graphics/text.h>
  12. #include <graphics/gfxmacros.h>
  13.  
  14. #include <graphics/layers.h>
  15. #include <intuition/intuition.h>
  16. #include <libraries/dos.h>
  17. #include "threed.h"
  18.  
  19. #define FIXEDILLUMINATION
  20.  
  21. extern UBYTE title[] ;
  22.  
  23. extern struct Custom custom;
  24.  
  25. extern struct TmpRas tmpras;
  26.  
  27. extern struct BitMap bitmap0;
  28. extern struct BitMap bitmap1;
  29.  
  30. extern struct RastPort r[2];
  31. extern struct RastPort *rp[2];
  32.  
  33. extern struct RasInfo ri[2];
  34. extern struct RasInfo *rip[2];
  35.  
  36. extern struct RasInfo *irip;
  37.  
  38. extern WORD pcount ;
  39. extern WORD vcount ;
  40.  
  41. extern UWORD frametoggle ;
  42.  
  43. extern BPTR objectsegment ;
  44.  
  45. extern struct Object *Amiga ;
  46.  
  47. extern long GfxBase;
  48. extern long DosBase;
  49.  
  50. extern int (*subroutines[])();
  51.  
  52. /******************************************************************************/
  53.  
  54. displayuniverse(view,screen,window,cameraobjectinfo,objectinfo)
  55. struct View *view;
  56. struct Screen *screen;
  57. struct Window *window;
  58. struct Objectinfo *cameraobjectinfo;
  59. struct Objectinfo *objectinfo;
  60. {
  61.     int argc = 0;
  62.     char *argv[MAXNUMARGS];
  63.     struct Objectinfo *thisobjectinfo; 
  64.  
  65. /* set up parameter passing information for this display */
  66.  
  67.     argv[0] = &thisobjectinfo;
  68.     argv[1] = subroutines;
  69.  
  70.     argc = 2;
  71.  
  72. /* PROCESS ALL THE OBJECTS IN THE LIST POINTED TO BY OBJECTINFO */
  73.  
  74.     thisobjectinfo = objectinfo;
  75.  
  76.     while(thisobjectinfo)
  77.     {
  78.    int thisobjecterror = FALSE;
  79.  
  80.    /* process this object */
  81.  
  82.    if(thisobjectinfo->objectprocedure)
  83.    {
  84.        int (*function)();
  85.  
  86.        /* call the object's procedure */
  87.  
  88. #ifdef ODEBUG
  89.        printf("do3d: object(%lx) procedure = %lx\n",thisobjectinfo,thisobjectinfo->objectprocedure);
  90. #endif
  91.        function = (thisobjectinfo->objectprocedure);
  92.        thisobjecterror = (*function)(argc,argv);
  93.     
  94.    }
  95.  
  96.    /* begin - rotate the object matrix - temporary */
  97.  
  98.    /* yaw(thisobjectinfo->objectmatrix,SINB,COSB); */
  99.  
  100.    /* pitch(thisobjectinfo->objectmatrix,SINB,COSB); */
  101.  
  102.    /* roll(thisobjectinfo->objectmatrix,SINB,COSB); */
  103.  
  104.    /* end - rotate the object matrix - temporary */
  105.  
  106.  
  107.    /* this objects's universal reference display matrix is trivial */
  108.    
  109.    *thisobjectinfo->displaymatrix = *thisobjectinfo->objectmatrix;
  110.  
  111.    /* this objects's universal reference position is trivial */
  112.    
  113.    *thisobjectinfo->displayposition = *thisobjectinfo->objectposition;
  114.  
  115.    /* process any subobjects dependent on this object before diplaying it */
  116.  
  117.    {
  118.        struct Objectinfo *thisubobjectinfo;
  119.  
  120.        thisubobjectinfo = thisobjectinfo->subobjectinfo;
  121.  
  122.        while(thisubobjectinfo)
  123.        {
  124.       /* display each subobject */
  125.  
  126.       subdisplayuniverse(view,screen,window,cameraobjectinfo,thisobjectinfo,thisubobjectinfo);
  127.  
  128.       thisubobjectinfo = thisubobjectinfo->nextobjectinfo;
  129.  
  130.        }
  131.  
  132.    }
  133.  
  134.    {
  135.        struct Coordinate centerpoint;
  136.  
  137.        /* concatenate this object's matrix with the camera matrix for display through camera viewpoint */
  138.  
  139.        {
  140.       struct UV uv;
  141.         
  142.       uv = *thisobjectinfo->objectmatrix; /* copy matrix */
  143.            
  144.  
  145.       cat(thisobjectinfo->displaymatrix,&uv,cameraobjectinfo->objectmatrix);
  146.  
  147.        }
  148.       
  149.        subvect(cameraobjectinfo->objectposition,thisobjectinfo->displayposition,¢erpoint);
  150.  
  151.        matrix(¢erpoint,¢erpoint,cameraobjectinfo->objectmatrix);
  152.        if ( (centerpoint.z > 0)
  153.           &&
  154.           (( (centerpoint.z) - ( (centerpoint.x < 0) ? -centerpoint.x : centerpoint.x )) > 0)
  155.           &&
  156.           (( (centerpoint.z) - ( (centerpoint.y < 0) ? -centerpoint.y : centerpoint.y )) > 0) )
  157.        {
  158.  
  159.       /* rotate the 3d normals*/
  160.  
  161. #ifdef DEBUG
  162.       printf("do3d: rotate the 3d normals\n");
  163. #endif
  164.  
  165.       rotate(thisobjectinfo->displaymatrix,thisobjectinfo->objectnumnormals,thisobjectinfo->objectnormals,thisobjectinfo->objectbufnormals);
  166.  
  167.       /* rotate, translate, and perspect the 3d points */
  168.  
  169.       dopoints(thisobjectinfo->displaymatrix,¢erpoint,thisobjectinfo->objectnumpoints,thisobjectinfo->objectpoints,thisobjectinfo->objectbufpoints);
  170.  
  171.        }
  172.        else
  173.        {
  174.            /* this object out of 45 degree frustrum */
  175.  
  176.            thisobjectinfo = thisobjectinfo->nextobjectinfo;
  177.  
  178.                 /* so process the next object */
  179.  
  180.            continue;
  181.             }
  182.  
  183.    }
  184.         
  185.     /* draw the polygons by traversing the polygon list */
  186.  
  187.     {
  188.    WORD polycount = 0;
  189.    WORD *nextcolor;
  190.    struct Coordinate **nextn;
  191.    struct Coordinate **nextp;
  192.    struct Coordinate *lastn = 0;
  193.    WORD endflag = FALSE;
  194.  
  195.    /* intialize buffer pointers */
  196.  
  197.    nextcolor = thisobjectinfo->colorbuf;
  198.    nextn = thisobjectinfo->nptrbuf;
  199.    nextp = thisobjectinfo->pptrbuf;
  200.  
  201.    for(polycount = 0; polycount < thisobjectinfo->objectnumpolys; polycount++)
  202.    {
  203.        struct Polygon **np;
  204.        WORD vc;
  205.        struct Coordinate **v;
  206.        struct Coordinate *n;
  207.        struct Coordinate *c0;
  208.        struct Coordinate *c1;
  209.        struct Coordinate *c2;
  210.        WORD bright;
  211.        WORD firstx, firsty;
  212.  
  213. #ifdef DEBUG
  214.        printf("poly %lx: \n",polycount);
  215. #endif
  216.        np = (thisobjectinfo->objectpolys+polycount);
  217.  
  218. #ifdef DEBUG
  219.        printf("np = %lx\n",np);
  220. #endif
  221.  
  222. #ifdef DEBUG
  223.        printf("vertexcount = %lx\n",(*np)->vertexcount);
  224. #endif
  225.  
  226. #ifdef DRAWDEBUG
  227.        printf("poly %lx: color = %lx\n",polycount,*nextcolor);
  228. #endif
  229.  
  230.        /* backface removal */
  231.  
  232.        /* first, simple clip */
  233.        if (((*nextn)->z) > 0) 
  234.        {
  235.       nextcolor++;
  236.       nextn++;
  237.       nextp = (nextp+((*np)->vertexcount));
  238.       continue;
  239.        }
  240.        
  241.        /* now, test z component of dynamically computed polygon normal */
  242.        
  243.        c0 = (struct Coordinate *)(*(nextp));
  244.        c1 = (struct Coordinate *)(*(nextp+1));
  245.        c2 = (struct Coordinate *)(*(nextp+2));
  246.  
  247.        /* if polygon's normal faces away from the screen, or is perpendicular, ignore it */
  248.  
  249. #ifdef DRAWDEBUG
  250.        printf("c0->x = %lx c0->y = %lx\n",c0->x,c0->y); 
  251.        printf("c1->x = %lx c1->y = %lx\n",c1->x,c1->y); 
  252.        printf("c2->x = %lx c2->y = %lx\n",c2->x,c2->y); 
  253. #endif
  254.  
  255.        /* fine clipping */
  256.  
  257.        if (((smuls(((c1->x)-(c0->x)),((c2->y)-(c1->y))))-(smuls(((c2->x)-(c1->x)),((c1->y)-(c0->y))))) >= 0)
  258.        {
  259.       nextcolor++;
  260.       nextn++;
  261.       nextp = (nextp+((*np)->vertexcount));
  262.       continue;
  263.        }
  264.  
  265.        /* illumination */
  266.  
  267. #ifndef FIXEDILLUMINATION
  268.  
  269.        bright = (((-(((*nextn)->x+(*nextn)->y))>>1)+(0x4000))>>11);
  270. #else
  271.  
  272.        bright = (WORD)*nextcolor;
  273. #endif
  274.        /* ceiling */
  275.  
  276.        bright = (bright > 0xF)?0xF:bright;
  277.  
  278. #ifdef DRAWDEBUG
  279.        printf("poly %lx: bright = %lx\n",polycount,bright);
  280. #endif
  281.  
  282.             for(vc = 0; vc < (*np)->vertexcount; vc++)
  283.        {
  284.       WORD x,y;
  285. #ifdef DRAWDEBUG
  286.       printf("vertex %lx : (thisobjectinfo->objectbufpoints+poff) = %lx\n",vc,*nextp);
  287. #endif
  288.  
  289. #ifdef DRAWDEBUG
  290.       printf("(thisobjectinfo->objectbufpoints+poff)->x = %lx\n",(*nextp)->x);
  291.       printf("(thisobjectinfo->objectbufpoints+poff)->y = %lx\n",(*nextp)->y);
  292.       printf("(thisobjectinfo->objectbufpoints+poff)->z = %lx\n",(*nextp)->z);
  293. #endif
  294.  
  295.       /* draw stuff in */
  296.  
  297. #ifdef DRAWDEBUG
  298.       printf("SetAPen = bright\n");
  299. #endif
  300.       SetAPen(rp[frametoggle ^ 0x0001],bright);
  301.  
  302.       if(vc == 0)
  303.       {
  304.  
  305.           /* open this polygon */
  306. #ifdef DRAWDEBUG
  307.           printf("call areamove...\n");
  308. #endif
  309.           x = (((*nextp)->x)+(TMPWIDTH>>1));
  310.           y = (((*nextp)->y)+(TMPHEIGHT>>1));
  311.  
  312.           if (x<0) x = 0;
  313.           if (y<0) y = 0;
  314.           if (x>TMPWIDTH-1) x = TMPWIDTH-1;
  315.           if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
  316.  
  317.           x -= ( ( TMPWIDTH  - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
  318.           y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
  319.  
  320.           firstx = x;
  321.           firsty = y;
  322.  
  323.           /* move into the raster that we're NOT displaying */
  324.  
  325. #ifndef FIXEDILLUMINATION
  326.           if( (lastn != *nextn) && (endflag) )
  327.           {
  328.               AreaEnd(rp[frametoggle ^ 0x0001]);
  329.          endflag = FALSE;
  330.           }
  331. #endif
  332.  
  333.           AreaMove(rp[frametoggle ^ 0x0001],x,y);
  334.  
  335.       }
  336.       else
  337.       {
  338.  
  339.           /* continue this polygon */
  340. #ifdef DRAWDEBUG
  341.           printf("call areadraw...\n");
  342. #endif
  343.           x = (((*nextp)->x)+(TMPWIDTH>>1));
  344.           y = (((*nextp)->y)+(TMPHEIGHT>>1));
  345.  
  346.           if (x<0) x = 0;
  347.           if (y<0) y = 0;
  348.           if (x>TMPWIDTH-1) x = TMPWIDTH-1;
  349.           if (y>TMPHEIGHT-1) y = TMPHEIGHT-1;
  350.  
  351.           x -= ( ( TMPWIDTH  - (window->RPort->BitMap->BytesPerRow<<3) ) >> 1 );
  352.           y -= ( ( TMPHEIGHT - (window->RPort->BitMap->Rows) ) >> 1 );
  353.  
  354.           /* draw into the raster that we're NOT displaying */
  355.  
  356.           AreaDraw(rp[frametoggle ^ 0x0001],x,y);
  357.  
  358.       }
  359.  
  360.       /* increment the nextp pointer */
  361.  
  362.       nextp++;
  363.  
  364.         }
  365.  
  366.        /* close this polygon */
  367.  
  368. #ifdef DRAWDEBUG
  369.        printf("call areaend...\n");
  370. #endif
  371.        /* end raster that we're NOT displaying (or continue collecting polygons) */
  372.  
  373.        /* last polygon displayed is this one */
  374.  
  375.        lastn = *nextn;
  376.  
  377. #ifndef FIXEDILLUMINATION
  378.        if(lastn  == *(nextn+1))
  379.        {
  380.       /* last polygon displayed has same normal as next polygon to be displayed */
  381.  
  382. #ifdef DRAWDEBUG
  383.       printf("last poly displayed has same normal as next polygon to be displayed...draw\n");
  384. #endif
  385.       /* draw, but do not terminate this polygon in this sequence */
  386.  
  387.       /* note : need graphics 28.5 or greater to do following trick ! */
  388.  
  389.       AreaDraw(rp[frametoggle ^ 0x0001],firstx,firsty);
  390.       endflag = TRUE;
  391.  
  392.       /* if graphics 28.4 or less  do this standard thing */
  393.  
  394.       /* AreaEnd(rp[frametoggle ^ 0x0001]); */
  395.       /* endflag = FALSE; */
  396.        }
  397.        else
  398.        {
  399.       /* last polygon displayed has different normal from next polygon to be displayed */
  400.  
  401. #ifdef DRAWDEBUG
  402.       printf("last poly displayed has deffernt normal from next polygon to be displayed...end\n");
  403. #endif
  404.       /* terminate this polygon sequence */
  405.  
  406.       AreaEnd(rp[frametoggle ^ 0x0001]);
  407.       endflag = FALSE;
  408.  
  409.        }
  410. #else
  411.        {
  412.       /* terminate this polygon sequence */
  413.  
  414.       AreaEnd(rp[frametoggle ^ 0x0001]);
  415.       endflag = FALSE;
  416.  
  417.        }
  418. #endif
  419.  
  420.        /* increment nextcolor, nextn pointers */
  421.  
  422.        nextcolor++;
  423.        nextn++;
  424.        
  425.    }
  426.  
  427.    if(endflag)
  428.    {
  429.        /* terminate series of "same normal" polygons after polyloop exit */
  430.  
  431. #ifdef DRAWDEBUG
  432.        printf("close last polygon in series...\n");
  433. #endif
  434.        AreaEnd(rp[frametoggle ^ 0x0001]);
  435.    }
  436.    
  437.     }
  438.  
  439.     thisobjectinfo = thisobjectinfo->nextobjectinfo;
  440.  
  441.     } /* end while (thisobject) */
  442.  
  443. }
  444.